package com.tanhua.server.service;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.convert.Convert;
import cn.hutool.core.util.RandomUtil;
import com.alibaba.fastjson.JSON;
import com.tanhua.autoconfig.template.HuanXinTemplate;
import com.tanhua.commons.utils.Constants;
import com.tanhua.dubbo.api.*;
import com.tanhua.model.domain.*;
import com.tanhua.model.domain.dto.RecommendUserDto;
import com.tanhua.model.domain.mongo.RecommendUser;
import com.tanhua.model.domain.mongo.Visitors;
import com.tanhua.model.domain.mysql.Question;
import com.tanhua.model.domain.mysql.UserInfo;
import com.tanhua.model.domain.vo.NearUserVo;
import com.tanhua.server.exception.BusinessException;
import com.tanhua.server.exception.ErrorResult;
import com.tanhua.server.interceptor.UserHolder;
import org.apache.dubbo.config.annotation.DubboReference;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import java.text.SimpleDateFormat;
import java.util.*;

/**
 * @author lk
 * @date 2022-03-25
 */
@Service
public class TanHuaService {
    @Autowired
    private HuanXinTemplate huanXinTemplate;

    @DubboReference
    private VisitorsApi visitorsApi;

    @DubboReference
    private RecommendUserApi recommendUserApi;

    @DubboReference
    private UserInfoApi userInfoApi;

    @DubboReference
    private QuestionApi questionApi;

    @DubboReference
    private UserLikeApi userLikeApi;

    @DubboReference
    private UserLocationApi userLocationApi;

    @Autowired
    private MessagesService messagesService;

    @Autowired
    private RedisTemplate<String, String> redisTemplate;

    @Value("${tanhua.default.recommend.users}")
    private String defaultRecommendUser;

   /* @Autowired
    private HuanXinTemplate template;*/

    public TodayBest todayBest() {
        //1、获取用户id
        Long userId = UserHolder.getUserId();
        //调用API 获取今日佳人数据
        RecommendUser recommendUser = recommendUserApi.queryWithMaxScore(userId);
        if (recommendUser == null) {
            //如果今日佳人为,则设置默认的值
            recommendUser = new RecommendUser();
            recommendUser.setUserId(1L);
            recommendUser.setScore(99d);
        }

        //T调用API 获取今日佳人数据
        UserInfo userInfo = userInfoApi.findById(recommendUser.getUserId());
        TodayBest vo = TodayBest.init(userInfo, recommendUser);
        return vo;

    }

    //查询分页推荐好友列表
    public PageResult recommendation(RecommendUserDto dto) {
        //获取用户id
        Long toUserId = UserHolder.getUserId();
        //调用recommendUserApi获取分页查询数据列表
        PageResult pr = recommendUserApi.queryRecommendUserList(dto.getPage(), dto.getPagesize(), toUserId);
        //获取分页中RecommendUser数据列表
        List<RecommendUser> items = (List<RecommendUser>) pr.getItems();

        //判断获取的分页数据是否为空
        if (items == null || items.size() <= 0) {
            return pr;
        }
        //使用工具类 获取所有推荐用户的id
        List<Long> userIds = CollUtil.getFieldValues(items, "userId", Long.class);
        //设置推荐的用户信息条件
        UserInfo userInfo = new UserInfo();
        userInfo.setAge(dto.getAge());
        userInfo.setGender(dto.getGender());
        //构建查询条件，批量查询所有的用户详情
        Map<Long, UserInfo> map = userInfoApi.findByIds(userIds, userInfo);
        //循环推荐的数据列表，构建vo对象
        List<TodayBest> list = new ArrayList<>();
        for (RecommendUser item : items) {
            //通过推荐用户列表来获取查询出来的用户数据,来判断是否为空
            UserInfo info = map.get(item.getUserId());
            if (info != null) {
                TodayBest vo = TodayBest.init(info, item);
                list.add(vo);
            }
        }
        //构造返回值
        pr.setItems(list);
        return pr;
    }

    /**
     * 查看佳人详情
     */
    public TodayBest personalInfo(Long userId) {
        //根据用户id查询用户详情
        UserInfo userInfo = userInfoApi.findById(userId);
        //根据操作人id和查看的用户id，查询两者的缘分值
        RecommendUser recommendUser = recommendUserApi.queryByUserId(userId, UserHolder.getUserId());
        //构造返回值
        TodayBest init = TodayBest.init(userInfo, recommendUser);

        //保存访问信息
        Visitors visitors = new Visitors();//构造访问信息对象
        visitors.setVisitDate(new SimpleDateFormat("yyyyMMdd").format(new Date()));
        visitors.setDate(System.currentTimeMillis());
        visitors.setVisitorUserId(UserHolder.getUserId());
        visitors.setUserId(userInfo.getId());
        visitors.setScore(recommendUser.getScore());
        visitors.setFrom("圈子");
        visitorsApi.saveVisitor(visitors);

        return init;
    }

    /**
     * 查看陌生人问题
     */
    public String strangerQuestions(Long userId) {
        Question question = questionApi.findByUserId(userId);
        return question == null ? "你知道我为什么眼里常含泪水吗?" : question.getTxt();
    }

    /**
     * 回复陌生人问题
     */
    public void replyQuestions(Long userId, String reply) {
        //查询自己的详细信息
        Long currentUserId = UserHolder.getUserId();
        UserInfo userInfo = userInfoApi.findById(currentUserId);
        //构造消息数据
        Map map = new HashMap();
        map.put("userId", currentUserId);
        map.put("nickname", userInfo.getNickname()); //昵称
        map.put("huanXinId", Constants.HX_USER_PREFIX + currentUserId);
        map.put("strangerQuestion", strangerQuestions(userId)); //调用方法获取陌生人问题
        map.put("reply", reply);
        //将map转为json格式
        String jsonString = JSON.toJSONString(map);
        //调用template对象，发送消息
        Boolean aBoolean = huanXinTemplate.sendMsg(Constants.HX_USER_PREFIX + userId, jsonString);
        if (!aBoolean) {
            throw new BusinessException(ErrorResult.messageError());
        }
    }

    /**
     * 探花-推荐用户列表
     */
    public List<TodayBest> queryCardsList() {
        //调用推荐API查询数据列表 并且 排除喜欢/不喜欢的用户，数量限制
        List<RecommendUser> users = recommendUserApi.queryCardsList(UserHolder.getUserId(), 10);
        //判断数据是否存在，如果不存在，构造默认数据 1,2,3
        if (CollUtil.isEmpty(users)) {
            String[] split = defaultRecommendUser.split(",");
            for (String s : split) {
                RecommendUser recommendUser = new RecommendUser();
                recommendUser.setToUserId(UserHolder.getUserId());
                recommendUser.setUserId(Convert.toLong(s));
                recommendUser.setScore(RandomUtil.randomDouble(60, 90));
                users.add(recommendUser);
            }
        }
        //构造返回的VO对象
        List<TodayBest> todayBestList = new ArrayList<>();
        //将推荐的用户id抽取出来
        List<Long> userIds = CollUtil.getFieldValues(users, "userId", Long.class);
        //查询推荐用户的详细信息
        Map<Long, UserInfo> infoMap = userInfoApi.findByIds(userIds, null);

        for (RecommendUser user : users) {
            UserInfo userInfo = infoMap.get(user.getUserId());
            TodayBest init = TodayBest.init(userInfo, user);
            todayBestList.add(init);
        }
        return todayBestList;
    }

    //右滑 喜欢
    public void likeUser(Long likeUserId) {
        //保存喜欢数据
        Boolean save = userLikeApi.saveOrUpdate(likeUserId, UserHolder.getUserId(), true);
        if (!save) {
            throw new BusinessException(ErrorResult.error());
        }
        //操作redis，写入喜欢的数据，删除不喜欢的数据 (喜欢的集合，不喜欢的集合)
        redisTemplate.opsForSet().remove(Constants.USER_NOT_LIKE_KEY + UserHolder.getUserId(), likeUserId.toString());
        redisTemplate.opsForSet().add(Constants.USER_LIKE_KEY + UserHolder.getUserId(), likeUserId.toString());
        //判断是否双向喜欢
        if (isLike(UserHolder.getUserId(), likeUserId)) {
            //添加好友
            messagesService.contacts(likeUserId);
        }
    }

    //左划 不喜欢
    public void unlikeUser(Long likeUserId) {
        //保存不喜欢数据
        Boolean save = userLikeApi.saveOrUpdate(likeUserId, UserHolder.getUserId(), false);
        if (!save) {
            throw new BusinessException(ErrorResult.error());
        }
        //操作redis，写入不喜欢的数据，删除喜欢的数据 (喜欢的集合，不喜欢的集合)
        redisTemplate.opsForSet().add(Constants.USER_NOT_LIKE_KEY + UserHolder.getUserId(), likeUserId.toString());
        redisTemplate.opsForSet().remove(Constants.USER_LIKE_KEY + UserHolder.getUserId(), likeUserId.toString());
    }

    //判断是否双向喜欢
    public Boolean isLike(Long userId, Long likeUserId) {
        String key = Constants.USER_LIKE_KEY + userId;
        return redisTemplate.opsForSet().isMember(key, likeUserId.toString());
    }

    //搜附近
    public List<NearUserVo> queryNearUser(String gender, String distance) {
        //调用API查询附近的用户（返回的是附近的人的所有用户id，包含当前用户的id）
        List<Long> userIds = userLocationApi.queryNearUser(UserHolder.getUserId(), Double.valueOf(distance));
        //判断集合是否为空
        if (CollUtil.isEmpty(userIds)) {
            return new ArrayList<>();
        }
        //构造查询条件
        UserInfo userInfo = new UserInfo();
        userInfo.setGender(gender);
        Map<Long, UserInfo> map = userInfoApi.findByIds(userIds, userInfo);
        //构造返回值
        List<NearUserVo> vos = new ArrayList<>();
        for (Long userId : userIds) {
            //排除当前用户
            if (userId == UserHolder.getUserId()) {
                continue;
            }
            UserInfo info = map.get(userId);
            if (info != null) {
                NearUserVo init = NearUserVo.init(info);
                vos.add(init);
            }
        }
        return vos;
    }
}
